//
//  ProfileController.swift
//  用户信息界面
//
//  Created by smile on 2019/4/27.
//  Copyright © 2019 ixuea. All rights reserved.
//

import UIKit

//TextView实现提示文字框架
import KMPlaceholderTextView

//导入响应式编程框架
import RxSwift

//发布订阅框架
import SwiftEventBus

class ProfileController: BaseTitleController {
    
    /// 头像容器
    @IBOutlet weak var svAvatar: UIStackView!
    
    /// 头像
    @IBOutlet weak var ivAvatar: UIImageView!
    
    /// 昵称容器
    @IBOutlet weak var svNickname: UIStackView!
    
    /// 昵称输入框
    @IBOutlet weak var tfNickname: UITextField!
    
    /// 性别容器
    @IBOutlet weak var svGender: UIStackView!
    
    /// 性别文本
    @IBOutlet weak var lbGender: UILabel!
    
    /// 生日容器
    @IBOutlet weak var svBrithday: UIStackView!
    
    /// 生日文本
    @IBOutlet weak var lbBrithday: UILabel!
    
    /// 区域容器
    @IBOutlet weak var svArea: UIStackView!
    
    /// 区域文本
    @IBOutlet weak var lbArea: UILabel!
    
    /// 描述输入框
    @IBOutlet weak var tvDescription: KMPlaceholderTextView!
    
    /// 手机号文本
    @IBOutlet weak var lbPhone: UILabel!
    
    /// 邮件文本
    @IBOutlet weak var lbEmail: UILabel!
    
    /// QQ按钮
    @IBOutlet weak var btQQ: UIButton!
    
    /// 微博按钮
    @IBOutlet weak var btWeibo: UIButton!
    
    /// 用来保存选择的省
    var procince:AddressModel?
    
    /// 用来保存选择的市
    var city:AddressModel?
    
    /// 用来保存选择的区
    var area:AddressModel?
    
    /// 用来保存选择的生日
    var birthday:String?

    /// 用来保存选择的性别
    var gender:Int?
    
    var avatarFilename:String?
    
    var data:User!
    
    override func initViews() {
        super.initViews()
        
        setTitle("我的资料")
        
        //圆角
        ViewUtil.showRadius(ivAvatar, 30)
        
        ViewUtil.showRadius(btQQ, 15)
        ViewUtil.showRadius(btWeibo, 15)
        
        //创建右侧保存按钮
        let saveBarItem = UIBarButtonItem(title: "保存", style: .plain, target: self, action: #selector(onSaveClick(sender:)))
        
        //将BarItem设置到导航栏右侧
        navigationItem.rightBarButtonItem=saveBarItem
    }
    
    /// 更新用户资料
    ///
    /// - Parameter sender: <#sender description#>
    @objc func onSaveClick(sender:UIButton) {
        print("ProfileController onSaveClick")
        
        //这里就不判断用户是否更改了资料
        //只要点击保存就更新
        
        updateUserInfo(nickname: tfNickname.text?.trim(), desc: tvDescription.text.trim(), gender: gender, birthday: birthday, province: procince?.region_name, province_code: procince?.region_id, city: city?.region_name, city_code: city?.region_id, area: area?.region_name, area_code: area?.region_id)
    }
    
    override func initDatas() {
        super.initDatas()
        
        fetchData()
    }
    
    func fetchData() {
        Api.shared
            .userDetail(PreferenceUtil.userId()!)
            .subscribeOnSuccess { (data) in
                if let data = data?.data {
                    self.showData(data)
                }
            }.disposed(by: disposeBag)
    }
    
    func showData(_ data:User) {
        self.data=data
        
        print("ProfileController showData:\(data.nickname!)")
        
        //显示头像
        ImageUtil.showAvatar(ivAvatar, data.avatar)
        
        /// 显示昵称
        tfNickname.text=data.nickname
        
        /// 显示性别
        lbGender.text=data.genderFormat
        
        /// 显示生日
        if let birthday = data.birthday {
            lbBrithday.text = birthday
        }
        
        //显示地区
        if let province = data.province {
            showArea(province, data.city!, data.area!)
        }
        
        /// 显示描述
        if let description = data.description {
            tvDescription.text = description
        }
        
        /// 显示手机号
        lbPhone.text=data.phone
        
        /// 显示邮件
        lbEmail.text=data.email
        
        if let _ = data.qq_id {
            //已经绑定了QQ
            showUnbindButtonStatus(btQQ)
        }else{
            //没有绑定QQ
            showBindButtonStatus(btQQ)
        }
        
        if let _ = data.weibo_id {
            //已经绑定了微博
            showUnbindButtonStatus(btWeibo)
        }else{
            //没有绑定微博
            showBindButtonStatus(btWeibo)
        }
    }
    
    /// 显示区域
    ///
    /// - Parameters:
    ///   - province: <#province description#>
    ///   - city: <#city description#>
    ///   - area: <#area description#>
    func showArea(_ province:String,_ city:String,_ area:String) {
        lbArea.text="\(province)-\(city)-\(area)"
    }
    
    /// 显示未绑定状态
    ///
    /// - Parameter view: <#view description#>
    func showUnbindButtonStatus(_ view:UIButton) {
        view.setTitle("已绑定", for: .normal)
        view.setTitleColor(UIColor.lightGray, for: .normal)
        view.showBorder(UIColor.lightGray)
        
    }
    
    /// 显示已经绑定状态
    ///
    /// - Parameter view: <#view description#>
    func showBindButtonStatus(_ view:UIButton) {
        view.setTitle("绑定", for: .normal)
        view.setTitleColor(UIColor(hex: COLOR_PRIMARY), for: .normal)
        view.showBorder(UIColor(hex: COLOR_PRIMARY))
    }
    
    override func initListeners() {
        super.initListeners()
        
        //头像点击
        svAvatar.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onAvatarClick)))
        
        //性别点击
        svGender.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onGenderClick)))
        
        //生日点击
        svBrithday.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onBrithdayClick)))
        
        //地区点击
        svArea.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onAreaClick)))
        
    }
    
    /// 头像容器点击回调方法
    @objc func onAvatarClick() {
        print("ProfileController onAvatarClick")

        //使用系统的图片选择器选择图片
        let picker = UIImagePickerController()
        
        //设置代理
        picker.delegate = self
        
        //选择源
        //photoLibrary：是相册库
        //还可以从摄像头选择
        picker.sourceType = .photoLibrary

        //允许编辑
        //选择完图片后
        //有一个裁剪框
        //但没法指定裁剪尺寸
        //或者比例
        
        //但可以手势缩放被裁剪的图片
        //在这里对我们来说够用了
        
        //头像不是说图片越小越好
        //因为万一要实现高清头像
        picker.allowsEditing = true

        //显示
        picker.modalTransitionStyle = .coverVertical
        
        //显示选择图片控制器
        present(picker, animated: true, completion: nil)
    }
    
    
    /// 性别容器点击回调方法
    @objc func onGenderClick() {
        print("ProfileController onGenderClick")
        
        //真实项目中会控制生日
        //不能选择当前以后的日志
        //这里就不实现了
        BHJPickerView(self, .gender).pickerViewShow()
    }
    
    /// 生日容器点击回调方法
    @objc func onBrithdayClick() {
        print("ProfileController onBrithdayClick")
        BHJPickerView(self, .date).pickerViewShow()
    }
    
    /// 区域容器点击回调方法
    @objc func onAreaClick() {
        print("ProfileController onAreaClick")
        
        //真实项目中
        //可以会实现弹出后
        //显示用户以前的位置
        //或者使用定位
        BHJPickerView(self, .address).pickerViewShow()
    }
    
    
    /// QQ按钮点击回调方法
    @IBAction func onQQClick(_ sender: Any) {
        print("ProfileController onQQClick")
        
        if let _ = data.qq_id {
            //已经绑定了QQ
            //弹出解绑提示对话框
            //因为我们的本质是要留住用户
            //或者防止用户误操作
            showUnbindDialog(PLATFORM_QQ)
        }else{
            //没有绑定QQ
            otherLogin(SSDKPlatformType.typeQQ)
        }
        
    }
    
    /// 微博按钮点击回调方法
    @IBAction func onWeiboClick(_ sender: Any) {
        print("ProfileController onWeiboClick")
        
        if let _ = data.weibo_id {
            //已经绑定了微博
            
            //弹出解绑提示对话框
            //因为我们的本质是要留住用户
            //或者防止用户误操作
            showUnbindDialog(PLATFORM_WEIBO)
        }else{
            //没有绑定微博
            otherLogin(SSDKPlatformType.typeSinaWeibo)
        }
        
    }
    
    /// 显示解绑提示对话框
    ///
    /// - Parameter platform: <#platform description#>
    func showUnbindDialog(_ platform:Int)  {
        //弹窗是可以封装的
        
        //添加一个弹窗
        //因为我们本质想留住用户
        let alertController = UIAlertController(title: "提示", message: "你确定解绑吗？", preferredStyle: .alert)
        
        //确定点击回调
        let confirmAction = UIAlertAction(title: "确定", style: .default) { (action) in
            self.unbindAccount(platform)
        }
        
        //取消点击回调
        let cancelAction = UIAlertAction(title: "取消", style: .default, handler: nil)
        
        //将这两个动作添加到控制器中
        alertController.addAction(confirmAction)
        alertController.addAction(cancelAction)
        
        //显示这个弹窗
        present(alertController, animated: true, completion: nil)
    }
    
    /// 解绑
    ///
    /// - Parameter platform: <#platform description#>
    func unbindAccount(_ platform:Int) {
        Api.shared
            .unbindAccount(platform)
            .subscribeOnSuccess { (data) in
                ToastUtil.short("解绑成功！")
            
                self.fetchData()
            }.disposed(by: disposeBag)
    }
    
    /// 第三方登陆
    ///
    /// - Parameter type: <#type description#>
    func otherLogin(_ type:SSDKPlatformType) {
        ShareSDK.getUserInfo(type) { (state:SSDKResponseState, user:SSDKUser?, error:Error?) in
            if SSDKResponseState.success==state {
                //登陆成功
                //这里可以获取到昵称，头像，OpenId(用户Id)
                let nickname=user?.nickname
                let avatar=user?.icon
                let openId=user?.credential.token
                
                //调用继续登陆方法
                self.continueLogin(type, nickname!, avatar!, openId!)
            }else if SSDKResponseState.cancel==state{
                //TODO 登陆取消处理
            }else{
                let nsError=error as! NSError
                print("login or register \(type) lgoin failed:\(nsError)")
                ToastUtil.short("登陆失败，请稍后再试！")
            }
        }
    }
    
    /// 继续登陆
    ///
    /// - Parameters:
    /// - Parameters:
    ///   - type: 登陆类型
    ///   - nickname: 昵称
    ///   - avatar: 头像
    ///   - openId: 第三方登陆后用户Id
    func continueLogin(_ type:SSDKPlatformType,_ nickname:String,_ avatar:String,_ openId:String) {
        //打印日志，方便调试
        print("ProfileController continueLogin \(type)  nickname:\(nickname) avatar:\(avatar) openId:\(openId)")
        
        
        var platform:Int!
        
        if SSDKPlatformType.typeQQ==type {
            //QQ第三方登陆
            platform=PLATFORM_QQ
        }else{
            //微博第三方登陆
            platform=PLATFORM_WEIBO
        }
        
        //调用接口将第三方用户的信息
        //绑定到当前登录的用户
        Api.shared.bindAccount(openId, platform).subscribeOnSuccess { (data) in
            ToastUtil.short("绑定成功！")
            
            self.fetchData()
        }.disposed(by: disposeBag)
        
    }
    
    /// 上传头像
    ///
    /// - Parameter data: <#data description#>
    func uploadAvatar(_ data:UIImage) {
        //由于头像一般比较小
        //同时也只有一张图片
        //所以可以不用显示加载框
        
        let oss=IxueaOSSUtil.shared()
        
        //在异步任务中上传图片
        DispatchQueue.global().async {
            //这里是子线程
    
                let putObjectRequest = OSSPutObjectRequest()
                putObjectRequest.bucketName=ALIYUN_OSS_BUCKET_NAME
                
                //上传
                //如果没有特殊需求建议不要分目录
                //因为当请求达到一定量级会有性能影响
                //如果一定要分目录
                //不要让目录名前面连续
                //例如时间戳倒过来
                self.avatarFilename="\(UUIDUtil.getUUID()).jpg"
                putObjectRequest.objectKey=self.avatarFilename!
                
                //将图片转为data数据
                //指令为50%
                //值越小质量越差
                //体积越小
                let imageData=data.jpegData(compressionQuality: 0.5)
                
                //直接上传NSData
                putObjectRequest.uploadingData = imageData!
                
                //上传进度
                putObjectRequest.uploadProgress={
                    bytesSent,totalByteSent,totalBytesExpectedToSend in
                    
                    //这里没用到
                    //所有就打印日志
                    //真实项目中可能会显示到图片上
                    print("PublishFeedController upload image progress:\(bytesSent) totalByteSent:\(totalByteSent) totalBytesExpectedToSend:\(totalBytesExpectedToSend)")
                }
                
                let putTask = oss.putObject(putObjectRequest)
                
                //上传完回调
                putTask.continue({ (task) -> Any? in
                    if task.error == nil {
                        print("PublishFeedController upload image success")
                        
                    } else {
                        //上传失败了
                        //真实项目可能会提示给用户
                        print("PublishFeedController upload image failed,error:\(task.error)")
                        self.avatarFilename=nil
                        
                    }
                    
                    return nil
                })
                
                //同步等待
                putTask.waitUntilFinished()
                
                //上传成功后
                //将图片名称
                //放到数组中
            }
            
            //所有图片上传完成
            DispatchQueue.main.async {
                //这里是主线程
                
                if let avatarFilename = self.avatarFilename {
                    //上传头像成功
                    self.updateUserInfo(avatar:avatarFilename)
                }else{
                    ToastUtil.short("上传头像失败，请稍后再试!")
                }
            }
    }
    
    
    /// 更新用户信息
    ///
    /// - Parameters:
    ///   - id: 用户Id
    ///   - nickname: 昵称
    ///   - avatar: 头像
    ///   - desc: 描述
    ///   - gender: 性别
    ///   - birthday: 生日
    ///   - province: 省
    ///   - province_code: 省代码
    ///   - city: 城市
    ///   - city_code: 城市代码
    ///   - area: 区
    ///   - area_code: 区代码
    func updateUserInfo(nickname:String?=nil,avatar:String?=nil,desc:String?=nil,gender:Int?=nil,birthday:String?=nil,province:String?=nil,province_code:String?=nil,city:String?=nil,city_code:String?=nil,area:String?=nil,area_code:String?=nil)  {
        
        Api.shared
            .updateUser(id:PreferenceUtil.userId()!,nickname: nickname, avatar: avatar, desc: desc, gender: gender, birthday: birthday, province: province, province_code: province_code, city: city, city_code: city_code, area: area, area_code: area_code)
            .subscribeOnSuccess { (data) in
                //更新成功
                //不提示任何信息
                
                //关闭当前界面
                //当然也可以不关闭
                //真实项目中根据业务需求调整就行了
                //发送通知
                SwiftEventBus.post(ON_UPDATE_USER_INFO, sender: nil)
                
                //关闭当前界面
                self.navigationController?.popViewController(animated: true)
                
            }.disposed(by: disposeBag)
        
    }

}

// MARK: - 启动界面
extension ProfileController{
    /// 启动界面
    ///
    static func start(_ navigationController:UINavigationController) {
        //创建控制器
        let controller=navigationController.storyboard?.instantiateViewController(withIdentifier: "Profile") as! ProfileController

        //将控制器压入导航控制中
        navigationController.pushViewController(controller, animated: true)
        
    }
}

// MARK: - 系统选择图片代理
extension ProfileController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    
    
    /// 取消了选择图片
    ///
    /// - Parameter picker: <#picker description#>
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        //关闭选择图片的控制器
        picker.dismiss(animated: true, completion: nil)
    }
    
    /// 选择了图片
    ///
    /// - Parameters:
    ///   - picker: <#picker description#>
    ///   - info: <#info description#>
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true, completion: nil)
        
        //获取编辑的后图片
        //如果没有编辑
        //需要通过其他字段获取
        if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
            //选择了图片
            print("ProfileController imagePickerController select image succes")

            uploadAvatar(image)
        }

    }
}

// MARK: - 选择器回调
extension ProfileController:PickerDelegate{
    
    /// 选择了地址
    ///
    /// - Parameters:
    ///   - pickerView: <#pickerView description#>
    ///   - procince: <#procince description#>
    ///   - city: <#city description#>
    ///   - area: <#area description#>
    func selectedAddress(_ pickerView: BHJPickerView, _ procince: AddressModel, _ city: AddressModel, _ area: AddressModel) {
        print("ProfileController selectedAddress:\(procince),\(city),\(area)")
        
        //保存到当前类中
        //点击保存的时候从这些字段上获取数据
        self.procince=procince
        self.city=city
        self.area=area
       
        //显示到界面
        showArea(procince.region_name!,city.region_name!,area.region_name!)
    }
    
    
    /// 选择日期
    ///
    /// - Parameters:
    ///   - pickerView: <#pickerView description#>
    ///   - dateStr: <#dateStr description#>
    func selectedDate(_ pickerView: BHJPickerView, _ dateStr: Date) {
        print("ProfileController selectedDate:\(dateStr)")
        
        self.birthday=TimeUtil.formatYMD(dateStr)
        
        lbBrithday.text = birthday
    }
    
    /// 选择性别
    ///
    /// - Parameters:
    ///   - pickerView: <#pickerView description#>
    ///   - genderStr: <#genderStr description#>
    func selectedGender(_ pickerView: BHJPickerView, _ genderStr: String) {
        print("ProfileController selectedGender:\(genderStr)")

        //真实项目要写到常量类中
        if "男" == genderStr {
            self.gender=1
        }else{
            //女
            self.gender=2
        }
        
        lbGender.text=genderStr
    }
    
}

